package com.micro.school.h5.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.micro.school.common.core.context.SecurityContextHolder;
import com.micro.school.common.core.domain.R;
import com.micro.school.common.core.web.domain.AjaxResult;
import com.micro.school.h5.domin.PayStudentFeePaymentH5;
import com.micro.school.h5.domin.StudentH5Info;
import com.micro.school.h5.domin.pay.LeShuaShare;
import com.micro.school.h5.domin.pay.LeShuaShareVo;
import com.micro.school.h5.util.DesUtil;
import com.micro.school.h5.util.HttpUtil;
import com.micro.school.h5.util.OrderNoGeneratorH5;
import com.micro.school.h5.util.SDKUtil;
import com.micro.school.system.api.RemoteOrderService;
import com.micro.school.system.api.RemoteUserService;
import com.micro.school.system.api.domain.vo.*;
import com.micro.school.system.api.factory.RemoteFileFallbackFactory;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("/confirm")
public class StudentConfirmController {

    @Resource
    private RemoteOrderService remoteOrderService;



    @Resource
    private RemoteUserService remoteUserService;

    /***
     *
     *预缴费查询
     */
    @PostMapping("/showRepayment")
    public AjaxResult showRepayment(@RequestBody StudentH5Info studentH5Info){
        log.info("查询学生预缴费信息，学生ID: {}", studentH5Info.getStudentId());
        //根据学生信息查询当前学生是否有预缴费
        PayStudentPrepaymentVos payStudentPrepaymentVos = new PayStudentPrepaymentVos();
        payStudentPrepaymentVos.setDeleteFlag("0");
        payStudentPrepaymentVos.setIsCancel(0);
        payStudentPrepaymentVos.setStudentId(Integer.valueOf(studentH5Info.getStudentId()));
        R<List<PayStudentPrepaymentVos>> studentPrepaymentVoList = remoteOrderService.getStudentPrepaymentNoVos(payStudentPrepaymentVos);
        List<PayStudentPrepaymentVos> data = studentPrepaymentVoList.getData();
        if (data != null && data.size() > 0){
            log.debug("查询到预缴费记录数量: {}", data.size());

            // 过滤掉已支付完成的记录(paymentStatus = 30)
            List<PayStudentPrepaymentVos> filteredData = new ArrayList<>();
            for (PayStudentPrepaymentVos prepayment : data) {
                if (prepayment.getPaymentStatus() != null && prepayment.getPaymentStatus() != 20) {
                    filteredData.add(prepayment);
                }
            }

            if (filteredData.isEmpty()) {
                log.info("学生ID: {} 没有可用的预缴费记录(已过滤支付完成的记录)", studentH5Info.getStudentId());
                return AjaxResult.success("没有预缴费", 0);
            }

            // 如果只有一条记录，直接使用
            if (filteredData.size() == 1) {
                PayStudentPrepaymentVos prepayment = filteredData.get(0);
                log.debug("只有一条可用预缴费记录，直接使用: ID={}, ChargeAmount={}, DeductionAmount={}, PaymentStatus={}",
                        prepayment.getId(),
                        prepayment.getChargeAmount(),
                        prepayment.getDeductionAmount(),
                        prepayment.getPaymentStatus());

                // 构建返回结果
                Map<String, Object> result = new HashMap<>();
                result.put("id", prepayment.getId());
                result.put("maxAmount",prepayment.getChargeAmount().subtract(prepayment.getDeductionAmount()).compareTo(BigDecimal.ZERO)>=0?prepayment.getChargeAmount().subtract(prepayment.getDeductionAmount()):BigDecimal.ZERO);
                result.put("prepaymentInfo", prepayment);

                String projectName = prepayment.getProjectName();
                if (projectName == null || projectName.isEmpty()) {
                    projectName = "未知项目";
                }
                result.put("projectName", projectName);

                log.info("学生ID: {} 预缴费查询完成，选中预缴费ID: {}", studentH5Info.getStudentId(), prepayment.getId());
                return AjaxResult.success("有预缴费", result);
            }

            // 查找ChargeAmount最大值的记录
            PayStudentPrepaymentVos maxChargePrepayment = filteredData.get(0);
            BigDecimal maxChargeAmount = maxChargePrepayment.getChargeAmount() != null ?
                    maxChargePrepayment.getChargeAmount() : BigDecimal.ZERO;

            for (PayStudentPrepaymentVos prepayment : filteredData) {
                BigDecimal chargeAmount = prepayment.getChargeAmount() != null ?
                        prepayment.getChargeAmount() : BigDecimal.ZERO;
                if (chargeAmount.compareTo(maxChargeAmount) > 0) {
                    maxChargeAmount = chargeAmount;
                    maxChargePrepayment = prepayment;
                }
            }

            // 在ChargeAmount最大的记录中，查找DeductionAmount最小的记录
            PayStudentPrepaymentVos bestPrepayment = maxChargePrepayment;
            BigDecimal minDeductionAmount = bestPrepayment.getDeductionAmount() != null ?
                    bestPrepayment.getDeductionAmount() : BigDecimal.ZERO;

            for (PayStudentPrepaymentVos prepayment : filteredData) {
                BigDecimal chargeAmount = prepayment.getChargeAmount() != null ?
                        prepayment.getChargeAmount() : BigDecimal.ZERO;

                // 只在ChargeAmount相同的记录中查找DeductionAmount最小的
                if (chargeAmount.compareTo(maxChargeAmount) == 0) {
                    BigDecimal deductionAmount = prepayment.getDeductionAmount() != null ?
                            prepayment.getDeductionAmount() : BigDecimal.ZERO;
                    if (deductionAmount.compareTo(minDeductionAmount) < 0) {
                        minDeductionAmount = deductionAmount;
                        bestPrepayment = prepayment;
                    }
                }
            }

            log.debug("选中的预缴费记录: ID={}, ChargeAmount={}, DeductionAmount={}, PaymentStatus={}",
                    bestPrepayment.getId(),
                    bestPrepayment.getChargeAmount(),
                    bestPrepayment.getDeductionAmount(),
                    bestPrepayment.getPaymentStatus());

            // 构建返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("id", bestPrepayment.getId());
            result.put("maxAmount", bestPrepayment.getChargeAmount().subtract(bestPrepayment.getDeductionAmount()).compareTo(BigDecimal.ZERO)>=0?bestPrepayment.getChargeAmount().subtract(bestPrepayment.getDeductionAmount()):BigDecimal.ZERO);
            result.put("prepaymentInfo", bestPrepayment);

            String projectName = bestPrepayment.getProjectName();
            if (projectName == null || projectName.isEmpty()) {
                projectName = "未知项目";
            }
            result.put("projectName", projectName);

            log.info("学生ID: {} 预缴费查询完成，选中预缴费ID: {}", studentH5Info.getStudentId(), bestPrepayment.getId());
            return AjaxResult.success("有预缴费", result);
        } else {
            log.info("学生ID: {} 没有预缴费记录", studentH5Info.getStudentId());
            return AjaxResult.success("没有预缴费", 0);
        }
    }



    //此接口仅用于如果抵扣金额等于支付金额，或者大于支付金额
    @PostMapping("/pay1")
    public AjaxResult pay1(@RequestBody PayStudentFeePaymentVos payStudentFeePaymentVos){
        //如果学生支付时修改了订单中的数量，则进行修改
        payStudentFeeUpdate(payStudentFeePaymentVos);
        //先对于预缴费进行编辑，防止其进行二次使用
        String usedPrepaymentId = payStudentFeePaymentVos.getUsedPrepaymentId();
        PayStudentPrepaymentVos payStudentPrepaymentVos = new PayStudentPrepaymentVos();
        payStudentPrepaymentVos.setDeleteFlag("0");
        payStudentPrepaymentVos.setIsCancel(0);
        payStudentPrepaymentVos.setId(Integer.valueOf(usedPrepaymentId));
        R<List<PayStudentPrepaymentVos>> prepaymentListR = remoteOrderService.getStudentPrepaymentVos(payStudentPrepaymentVos);
        String generatePayNo = OrderNoGeneratorH5.generatePayNo();
        if (prepaymentListR.getData() != null && prepaymentListR.getData().size() > 0){
            PayStudentPrepaymentVos prepayment = prepaymentListR.getData().get(0);
            //如果是已归集就不许使用
            if (prepayment.getCollectionStatus() == 30 && prepayment.getDeductionAmount().compareTo(prepayment.getChargeAmount()) == 0){
                return AjaxResult.error("此缴费已归集，请勿使用此抵扣");
            }else{
                //仅修改归集状态然后进行数据处理
                PayStudentPrepaymentVos payStudentPrepayment = new PayStudentPrepaymentVos();
                payStudentPrepayment.setId(prepayment.getId());
                payStudentPrepayment.setCollectionStatus(30);
                remoteOrderService.updateCollectionStatus(payStudentPrepayment);
                try {
                    log.info("开始进行金额计算----------------------");
                    List<PayStudentFeePaymentDetailVos> details = payStudentFeePaymentVos.getDetails();
                    //首先编辑参数  入库之后需要
                    payStudentFeePaymentVos.setTenantId(Long.valueOf(SecurityContextHolder.getUserTenantId()));
                    payStudentFeePaymentVos.setPayNo(generatePayNo);
                    payStudentFeePaymentVos.setBillNo(OrderNoGeneratorH5.generateOrderNo());
                    payStudentFeePaymentVos.setPayStatus(30L);
                    payStudentFeePaymentVos.setPaidAmount(BigDecimal.ZERO);
                    payStudentFeePaymentVos.setActualAmount(BigDecimal.ZERO);
                    payStudentFeePaymentVos.setCreateTime(new Date());
                    payStudentFeePaymentVos.setUpdateTime(new Date());
                    //所有详情的总额之和等于抵扣金额
                    BigDecimal totalMoney = details.stream().map(PayStudentFeePaymentDetailVos::getTotalAmount).reduce(BigDecimal::add).get();
                    if (totalMoney.compareTo(prepayment.getChargeAmount()) > 0) {
                        log.info("支付所需总金额: {}, 预缴费金额: {}", totalMoney, prepayment.getChargeAmount());
                        return AjaxResult.error("支付所需金额大于抵扣金额，请重新选择");
                    }
                    payStudentFeePaymentVos.setPrepaymentDeducted(totalMoney);
                    log.info("开始进行原账单同步修改----------------------");
                    //会进行原账单同步
                    remoteOrderService.insertPayStudentFeePayment(payStudentFeePaymentVos);

                    //进行支付详情输出入库
                    log.info("开始进行支付详情入库----------------------");
                    for (PayStudentFeePaymentDetailVos detail : details) {
                        //获取商户id
                        PayFeeItemConfigVos payFeeItemConfigVo = new PayFeeItemConfigVos();
                        payFeeItemConfigVo.setId(Math.toIntExact(detail.getFeeItemConfigId()));
                        PayFeeItemConfigVos payFeeItemConfigVos = remoteOrderService.selectMerchantByConfigId(payFeeItemConfigVo);
                        detail.setPayNo(generatePayNo);
                        detail.setStudentFeeItemId(detail.getStudentFeeItemId());
                        detail.setFeeItemConfigId(detail.getFeeItemConfigId());
                        detail.setUsedPrepaymentId(usedPrepaymentId);
                        detail.setMerchantPkId(Long.valueOf(payFeeItemConfigVos.getMerchantPkId()));
                        detail.setPayStatus(30L);
                        //详情的小计金额等于详情的抵扣金额
                        detail.setPrepaymentDeducted(detail.getTotalAmount());
                        //实际缴费0元
                        detail.setActualAmount(BigDecimal.ZERO);
                        detail.setCreateTime(new Date());
                        detail.setPaidAmount(BigDecimal.ZERO);
                        detail.setPayMethod(payStudentFeePaymentVos.getPayMethod());
                        //会进行原账单同步
                        remoteOrderService.insertPayStudentFeePaymentDetailVos(detail);
                    }
                    //均处理完成后进行预付款内容确认
                    //抵扣金额
                    log.info("开始进行预缴费金额修改----------------------");
                    if (prepayment.getChargeAmount().compareTo(payStudentFeePaymentVos.getTotalAmount().add(prepayment.getDeductionAmount())) > 0) {
                        PayStudentPrepaymentVos payStudentPrepaymentVos1 = new PayStudentPrepaymentVos();
                        payStudentPrepaymentVos1.setId(prepayment.getId());
                        payStudentPrepaymentVos1.setDeductionAmount(prepayment.getDeductionAmount().add(totalMoney));
                        payStudentPrepaymentVos1.setCollectedTime(new Date());
                        payStudentPrepaymentVos1.setPaymentStatus(30);
                        payStudentPrepaymentVos1.setLastPaidTime(new Date());
                        payStudentPrepaymentVos1.setUpdateTime(new Date());
                        remoteOrderService.updateStudentPrepayment(payStudentPrepaymentVos1);
                    }else if (prepayment.getChargeAmount().compareTo(payStudentFeePaymentVos.getTotalAmount().add(prepayment.getDeductionAmount())) == 0) {
                        PayStudentPrepaymentVos payStudentPrepaymentVos1 = new PayStudentPrepaymentVos();
                        payStudentPrepaymentVos1.setId(prepayment.getId());
                        payStudentPrepaymentVos1.setDeductionAmount(prepayment.getDeductionAmount().add(totalMoney));
                        payStudentPrepaymentVos1.setCollectedTime(new Date());
                        payStudentPrepaymentVos1.setPaymentStatus(20);
                        payStudentPrepaymentVos1.setLastPaidTime(new Date());
                        payStudentPrepaymentVos1.setUpdateTime(new Date());
                        payStudentPrepaymentVos1.setFinishTime(new Date());
                        remoteOrderService.updateStudentPrepayment(payStudentPrepaymentVos1);
                    }
                    log.info("开始进行学生订单展示内容入库----------------------");
                    R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId(payStudentFeePaymentVos.getStudentId(),payStudentFeePaymentVos.getFeeYearId());
                    remoteUserService.insertStudentPayVos(listR.getData());
                    return AjaxResult.success("抵扣金额成功！支付成功");
                }catch (Exception e){
                    //项目报错后修改归集状态
                    PayStudentPrepaymentVos payStudentPrepayment1 = new PayStudentPrepaymentVos();
                    payStudentPrepayment1.setId(prepayment.getId());
                    payStudentPrepayment1.setCollectionStatus(10);
                    remoteOrderService.updateCollectionStatus(payStudentPrepayment1);
                    log.info("抵扣金额失败，请重新支付：{}",e.getMessage());
                    return AjaxResult.error("金额修改出错，请重新支付");
                }
            }
        }else{
            return AjaxResult.error("没有此抵扣金额");
        }
    }

    private void payStudentFeeUpdate(PayStudentFeePaymentVos payStudentFeePaymentVos) {
        //detail
        List<PayStudentFeePaymentDetailVos> payStudentFeePaymentVosDetails = payStudentFeePaymentVos.getDetails();
        remoteOrderService.updateStudentFee(payStudentFeePaymentVosDetails);
        //查询原订单总金额
        PayStudentFeeVos payStudentFeeVos = remoteOrderService.queryStudentFeeByDetail(payStudentFeePaymentVos.getStudentFeeId());
        //统计现订单总金额
        BigDecimal totalAmount = remoteOrderService.sumStudentFee(payStudentFeePaymentVos.getStudentFeeId());
        if (BigDecimal.valueOf(payStudentFeeVos.getAmountPayable()).compareTo(totalAmount) != 0){
            //不相同就修改
            PayStudentFeeVos payStudentFeeVos1 = new PayStudentFeeVos();
            payStudentFeeVos1.setId(payStudentFeeVos.getId());
            payStudentFeeVos1.setAmountPayable(totalAmount.doubleValue());
            remoteOrderService.updateStudentFeeTotalMoney(payStudentFeeVos1);
        }
    }

    /**
     * 链接邮储开缴
     * */
    @PostMapping("/trans1")
    public AjaxResult trans1(@RequestBody PayStudentFeePaymentVos payStudentFeePaymentVos) {
        String cashierHtml="";
        if (payStudentFeePaymentVos.getUsedPrepaymentId() != null && !"".equals(payStudentFeePaymentVos.getUsedPrepaymentId())) {
            String usedPrepaymentId = payStudentFeePaymentVos.getUsedPrepaymentId();
            PayStudentPrepaymentVos payStudentPrepaymentVos = new PayStudentPrepaymentVos();
            payStudentPrepaymentVos.setDeleteFlag("0");
            payStudentPrepaymentVos.setIsCancel(0);
            payStudentPrepaymentVos.setId(Integer.valueOf(usedPrepaymentId));
            R<List<PayStudentPrepaymentVos>> prepaymentListR = remoteOrderService.getStudentPrepaymentVos(payStudentPrepaymentVos);
            String generatePayNo = OrderNoGeneratorH5.generatePayNo();
            if (prepaymentListR.getData() != null && prepaymentListR.getData().size() > 0){
                PayStudentPrepaymentVos prepayment = prepaymentListR.getData().get(0);
                //如果是已归集就不许使用
                if (prepayment.getCollectionStatus() == 30 && prepayment.getDeductionAmount().compareTo(prepayment.getChargeAmount()) == 0){
                    return AjaxResult.error("此缴费已归集，请勿使用此抵扣");
                }else{
                    //仅修改归集状态然后进行数据处理
                    PayStudentPrepaymentVos payStudentPrepayment = new PayStudentPrepaymentVos();
                    payStudentPrepayment.setId(prepayment.getId());
                    payStudentPrepayment.setCollectionStatus(30);
                    remoteOrderService.updateCollectionStatus(payStudentPrepayment);
                    try {
                        List<PayStudentFeePaymentDetailVos> details = payStudentFeePaymentVos.getDetails();
                        //首先编辑参数  入库之后需要
                        payStudentFeePaymentVos.setTenantId(Long.valueOf(SecurityContextHolder.getUserTenantId()));
                        payStudentFeePaymentVos.setPayNo(generatePayNo);
                        payStudentFeePaymentVos.setBillNo(OrderNoGeneratorH5.generateOrderNo());
                        payStudentFeePaymentVos.setPayStatus(30L);
                        payStudentFeePaymentVos.setPaidAmount(BigDecimal.ZERO);
                        payStudentFeePaymentVos.setActualAmount(BigDecimal.ZERO);
                        payStudentFeePaymentVos.setCreateTime(new Date());
                        payStudentFeePaymentVos.setUpdateTime(new Date());
                        //所有详情的总额之和等于抵扣金额
                        BigDecimal totalMoney = details.stream().map(PayStudentFeePaymentDetailVos::getTotalAmount).reduce(BigDecimal::add).get();
                        if (totalMoney.compareTo(prepayment.getChargeAmount()) > 0) {
                            log.info("支付所需总金额: {}, 预缴费金额: {}", totalMoney, prepayment.getChargeAmount());
                            return AjaxResult.error("支付所需金额大于抵扣金额，请重新选择");
                        }
                        payStudentFeePaymentVos.setPrepaymentDeducted(totalMoney);
                        //会进行原账单同步
                        remoteOrderService.insertPayStudentFeePayment(payStudentFeePaymentVos);
                        //进行支付详情输出入库

                        for (PayStudentFeePaymentDetailVos detail : details) {
                            //获取商户id
                            PayFeeItemConfigVos payFeeItemConfigVo = new PayFeeItemConfigVos();
                            payFeeItemConfigVo.setId(Math.toIntExact(detail.getFeeItemConfigId()));
                            PayFeeItemConfigVos payFeeItemConfigVos = remoteOrderService.selectMerchantByConfigId(payFeeItemConfigVo);
                            detail.setPayNo(generatePayNo);
                            detail.setStudentFeeItemId(detail.getStudentFeeItemId());
                            detail.setFeeItemConfigId(detail.getFeeItemConfigId());
                            detail.setUsedPrepaymentId(usedPrepaymentId);
                            detail.setMerchantPkId(Long.valueOf(payFeeItemConfigVos.getMerchantPkId()));
                            detail.setPayStatus(30L);
                            //详情的小计金额等于详情的抵扣金额
                            detail.setPrepaymentDeducted(detail.getTotalAmount());
                            //实际缴费0元
                            detail.setActualAmount(BigDecimal.ZERO);
                            detail.setCreateTime(new Date());
                            detail.setPaidAmount(BigDecimal.ZERO);
                            detail.setPayMethod(payStudentFeePaymentVos.getPayMethod());
                            //会进行原账单同步
                            remoteOrderService.insertPayStudentFeePaymentDetailVos(detail);
                        }
                        //均处理完成后进行预付款内容确认
                        //抵扣金额
                        if (prepayment.getChargeAmount().compareTo(payStudentFeePaymentVos.getTotalAmount().add(prepayment.getDeductionAmount())) > 0) {
                            PayStudentPrepaymentVos payStudentPrepaymentVos1 = new PayStudentPrepaymentVos();
                            payStudentPrepaymentVos1.setId(prepayment.getId());
                            payStudentPrepaymentVos1.setDeductionAmount(prepayment.getDeductionAmount().add(totalMoney));
                            payStudentPrepaymentVos1.setCollectedTime(new Date());
                            payStudentPrepaymentVos1.setPaymentStatus(30);
                            payStudentPrepaymentVos1.setLastPaidTime(new Date());
                            payStudentPrepaymentVos1.setUpdateTime(new Date());
                            remoteOrderService.updateStudentPrepayment(payStudentPrepaymentVos1);
                        }else if (prepayment.getChargeAmount().compareTo(payStudentFeePaymentVos.getTotalAmount().add(prepayment.getDeductionAmount())) == 0) {
                            PayStudentPrepaymentVos payStudentPrepaymentVos1 = new PayStudentPrepaymentVos();
                            payStudentPrepaymentVos1.setId(prepayment.getId());
                            payStudentPrepaymentVos1.setDeductionAmount(prepayment.getDeductionAmount().add(totalMoney));
                            payStudentPrepaymentVos1.setCollectedTime(new Date());
                            payStudentPrepaymentVos1.setPaymentStatus(20);
                            payStudentPrepaymentVos1.setLastPaidTime(new Date());
                            payStudentPrepaymentVos1.setUpdateTime(new Date());
                            payStudentPrepaymentVos1.setFinishTime(new Date());
                            remoteOrderService.updateStudentPrepayment(payStudentPrepaymentVos1);
                        }
                        R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId(payStudentFeePaymentVos.getStudentId(),payStudentFeePaymentVos.getFeeYearId());
                        remoteUserService.insertStudentPayVos(listR.getData());

                        Map<String, String> paramsMap = new TreeMap<String, String>();
                        paramsMap.put("merchant_id", "800000000948");
                        paramsMap.put("merchant_order_no", payStudentFeePaymentVos.getPayNo());
                        paramsMap.put("nonce_str", "41101101001215");
                        paramsMap.put("req_trace_id",payStudentFeePaymentVos.getBillNo());
                        paramsMap.put("openid","12580");
                        paramsMap.put("appid","678910");
                        paramsMap.put("order_infos", "学费");
                        paramsMap.put("return_url", "http://edu.leyibei.com/h5");
                        paramsMap.put("success_url", "http://edu.leyibei.com/h5");
                        paramsMap.put("staff_name", "1001");
                        paramsMap.put("total_amount", String.valueOf(payStudentFeePaymentVos.getPaidAmount()));
                        String resStr = SDKUtil.createLinkString(paramsMap, false, true, "UTF-8");
                        Map<String, String> bizData = new HashMap<>();
                        bizData.put("txtcode","1001");
                        bizData.put("req_date",String.valueOf(System.currentTimeMillis()));
                        bizData.put("sign", DesUtil.encryptECB("2MMB8UL3",resStr));
                        log.info("交易上送："+ JSON.toJSONString(bizData) );
                        String result = "";
                        result = HttpUtil.sendPostRequest(bizData, "https://fapi.leyibei.com/cashiersystem/desisv/wxappletPay");
                        log.info("邮储交易返回：" +JSON.toJSONString(result) );
                        JSONObject job=JSONObject.parseObject(result);
                        String response=job.getString("response");
                        String code =JSONObject.parseObject(response).getString("code");
                        String msg =JSONObject.parseObject(response).getString("msg");
                        String deStr="";
                        if(code.equals("000000")){
                            String sign=job.getString("sign");
                            deStr = DesUtil.decryptECB("2MMB8UL3", sign);
                            JSONObject deobj=JSONObject.parseObject(deStr);
                            cashierHtml=deobj.getString("pay_url");
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
        return AjaxResult.success(cashierHtml);
    }


    //邮储回调
    @PostMapping("/notify")
    @Transactional
    public AjaxResult trade(@RequestBody String notifyRequest) {
        //TODO回调进行数据处理，修改状态
        log.info("支付成功回调内容：{}",notifyRequest);
        PayStudentFeePaymentVos payStudentFeePaymentVos =new PayStudentFeePaymentVos();
        String payNo = "";
        com.alibaba.fastjson2.JSONObject paramsObj = JSON.parseObject(notifyRequest);
        String sign = paramsObj.getString("sign");
        com.alibaba.fastjson2.JSONObject obj = paramsObj.getJSONObject("response");
        String code = obj.getString("code");
        String msg = obj.getString("msg");
        if (code.equals("000000")) {
            try {
                String deStr = DesUtil.decryptECB("2MMB8UL3", sign);
                JSONObject resultobj = JSONObject.parseObject(deStr);
                String order_state = resultobj.getString("order_state");
                if (null != order_state) {
                    if (order_state.equals("SUCCESS")) {
                        payNo = resultobj.getString("out_order_no");
                        payStudentFeePaymentVos.setPayNo(payNo);
                        payStudentFeePaymentVos.setPayStatus(30L);
                        R<PayStudentFeePaymentVos> payStudentFeePaymentVosR = remoteOrderService.updateStudentFeePayment(payStudentFeePaymentVos);
                        R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId(payStudentFeePaymentVosR.getData().getStudentId(),payStudentFeePaymentVosR.getData().getFeeYearId());
                        remoteUserService.insertStudentPayVos(listR.getData());
                    }else{
                        payStudentFeePaymentVos.setPayNo(payNo);
                        payStudentFeePaymentVos.setPayStatus(40L);
                        R<PayStudentFeePaymentVos> payStudentFeePaymentVosR = remoteOrderService.updateStudentFeePayment(payStudentFeePaymentVos);
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }
        return null;
    }


    /**
     * 触发分账    缴费金额大于预缴费
     * */
    @PostMapping("/transShare")
    public AjaxResult transShare(@RequestBody PayStudentFeePaymentVos payStudentFeePaymentVos){
        if (payStudentFeePaymentVos.getUsedPrepaymentId() != null && !"".equals(payStudentFeePaymentVos.getUsedPrepaymentId())) {
            // 先对于预缴费进行编辑，防止其进行二次使用   有预缴费
            String usedPrepaymentId = payStudentFeePaymentVos.getUsedPrepaymentId();
            PayStudentPrepaymentVos payStudentPrepaymentVos = new PayStudentPrepaymentVos();
            payStudentPrepaymentVos.setDeleteFlag("0");
            payStudentPrepaymentVos.setId(Integer.valueOf(usedPrepaymentId));
            R<List<PayStudentPrepaymentVos>> prepaymentListR = remoteOrderService.getStudentPrepaymentVos(payStudentPrepaymentVos);

            String generatePayNo = OrderNoGeneratorH5.generatePayNo();
            String orderNo = OrderNoGeneratorH5.generateOrderNo();

            if (prepaymentListR.getData() != null && prepaymentListR.getData().size() > 0) {
                PayStudentPrepaymentVos prepayment = prepaymentListR.getData().get(0);
                // 如果是已归集就不许使用
                if (prepayment.getCollectionStatus() == 30) {
                    return AjaxResult.error("此缴费已归集，或正在缴费中，请勿使用此抵扣");
                } else {
                    // 仅修改归集状态然后进行数据处理
                    PayStudentPrepaymentVos payStudentPrepayment1 = new PayStudentPrepaymentVos();
                    payStudentPrepayment1.setId(prepayment.getId());
                    payStudentPrepayment1.setCollectionStatus(30);
                    remoteOrderService.updateCollectionStatus(payStudentPrepayment1);
                    try {
                        // 首先编辑参数  入库之后需要
                        payStudentFeePaymentVos.setPayNo(generatePayNo);
                        payStudentFeePaymentVos.setBillNo(orderNo);
                        payStudentFeePaymentVos.setPayStatus(20L);
                        payStudentFeePaymentVos.setCreateTime(new Date());
                        payStudentFeePaymentVos.setUpdateTime(new Date());
                        // 会进行原账单同步
                        remoteOrderService.insertPayStudentFeePayment(payStudentFeePaymentVos);
                        // 进行支付详情输出入库
                        List<PayStudentFeePaymentDetailVos> details = payStudentFeePaymentVos.getDetails();
                        for (PayStudentFeePaymentDetailVos detail : details) {
                            // 获取商户id
                            PayFeeItemConfigVos payFeeItemConfigVo = new PayFeeItemConfigVos();
                            payFeeItemConfigVo.setId(Math.toIntExact(detail.getFeeItemConfigId()));
                            PayFeeItemConfigVos payFeeItemConfigVos = remoteOrderService.selectMerchantByConfigId(payFeeItemConfigVo);
                            detail.setPayNo(generatePayNo);
                            detail.setPaymentId(Long.valueOf(payStudentFeePaymentVos.getId()));
                            detail.setUsedPrepaymentId(usedPrepaymentId);
                            detail.setMerchantPkId(Long.valueOf(payFeeItemConfigVos.getMerchantPkId()));
                            detail.setPayStatus(20L);
                            detail.setCreateTime(new Date());
                            // 会进行原账单同步
                            remoteOrderService.insertPayStudentFeePaymentDetailVos(detail);
                        }
                        // 同步后开始支付
                        // 拼装参数，进行支付内容发起
                        // 使用 merchantPkId 分组并计算 totalAmount 总和，同时查询商户信息
                        Map<Long, BigDecimal> merchantTotalMap = new HashMap<>();
                        Map<Long, MerMerchantVos> merchantInfoMap = new HashMap<>();
                        for (PayStudentFeePaymentDetailVos detail : details) {
                            Long merchantPkId = detail.getMerchantPkId();
                            BigDecimal totalAmount = detail.getTotalAmount();
                            // 累计计算相同商户的总额
                            merchantTotalMap.merge(merchantPkId, totalAmount, BigDecimal::add);
                            // 获取商户信息（仅获取一次）
                            if (!merchantInfoMap.containsKey(merchantPkId)) {
                                R<MerMerchantVos> merchantInfoR = remoteUserService.queryMerchantById(merchantPkId);
                                if (merchantInfoR.getData() != null) {
                                    merchantInfoMap.put(merchantPkId, merchantInfoR.getData());
                                }
                            }
                        }
                        // 构建分账结果列表
                        List<LeShuaShare> leShuaShareList = new ArrayList<>();
                        BigDecimal totalMoney = details.stream()
                                .map(PayStudentFeePaymentDetailVos::getTotalAmount)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                        for (Map.Entry<Long, BigDecimal> entry : merchantTotalMap.entrySet()) {
                            Long merchantPkId = entry.getKey();
                            BigDecimal shareMoney = entry.getValue();
                            // 获取商户信息
                            MerMerchantVos merchantInfo = merchantInfoMap.get(merchantPkId);
                            if (merchantInfo != null) {
                                LeShuaShare leShuaShare = new LeShuaShare();
                                leShuaShare.setMerchantId(12344L);
                                leShuaShare.setShareMerchantId(merchantPkId);
                                leShuaShare.setOrderId(orderNo);
                                leShuaShare.setTotalMoney(totalMoney);
                                leShuaShare.setMoney(shareMoney);
                                leShuaShare.setHighSchoolOrderId(generatePayNo);
                                leShuaShare.setStatus("0");
                                leShuaShare.setMerchantChannelCode("学校code");
                                leShuaShare.setShareChannelCode(merchantInfo.getMerchantCode());
                                leShuaShare.setMerchantName("学校名称");
                                leShuaShare.setShareName(merchantInfo.getMerchantName());
                                leShuaShare.setPaymentMethod(String.valueOf(payStudentFeePaymentVos.getPayMethod()));
                                leShuaShareList.add(leShuaShare);
                            }
                        }
                        LeShuaShareVo leShuaShareVo = new LeShuaShareVo();
                        leShuaShareVo.setShareMerchantList(leShuaShareList);
                        // 发送给乐刷分账处，进行支付并进行分账
                        R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId(payStudentFeePaymentVos.getStudentId(),payStudentFeePaymentVos.getFeeYearId());
                        remoteUserService.insertStudentPayVos(listR.getData());



                        return AjaxResult.success("抵扣金额成功！支付成功！");
                    } catch (Exception e) {
                        // 项目报错后修改归集状态
                        PayStudentPrepaymentVos payStudentPrepayment2 = new PayStudentPrepaymentVos();
                        payStudentPrepayment2.setId(prepayment.getId());
                        payStudentPrepayment2.setCollectionStatus(10);
                        remoteOrderService.updateCollectionStatus(payStudentPrepayment2);
                        log.info("抵扣金额失败，请重新支付：{}", e.getMessage());
                        return AjaxResult.error("金额修改出错，请重新支付");
                    }
                }
            } else {
                return AjaxResult.error("没有此抵扣金额");
            }
        }else{
            //无预缴费
            try {
                String generatePayNo = OrderNoGeneratorH5.generatePayNo();
                String orderNo = OrderNoGeneratorH5.generateOrderNo();
                // 首先编辑参数  入库之后需要
                payStudentFeePaymentVos.setTenantId(Long.valueOf(SecurityContextHolder.getUserTenantId()));
                payStudentFeePaymentVos.setPayNo(generatePayNo);
                payStudentFeePaymentVos.setBillNo(orderNo);
                payStudentFeePaymentVos.setPayStatus(20L);
                payStudentFeePaymentVos.setCreateTime(new Date());
                payStudentFeePaymentVos.setUpdateTime(new Date());
                // 会进行原账单同步
                remoteOrderService.insertPayStudentFeePayment(payStudentFeePaymentVos);
                // 进行支付详情输出入库
                List<PayStudentFeePaymentDetailVos> details = payStudentFeePaymentVos.getDetails();
                for (PayStudentFeePaymentDetailVos detail : details) {
                    // 获取商户id
                    PayFeeItemConfigVos payFeeItemConfigVo = new PayFeeItemConfigVos();
                    payFeeItemConfigVo.setId(Math.toIntExact(detail.getFeeItemConfigId()));
                    PayFeeItemConfigVos payFeeItemConfigVos = remoteOrderService.selectMerchantByConfigId(payFeeItemConfigVo);
                    detail.setPayNo(generatePayNo);
                    detail.setPaymentId(Long.valueOf(payStudentFeePaymentVos.getId()));
                    detail.setMerchantPkId(Long.valueOf(payFeeItemConfigVos.getMerchantPkId()));
                    detail.setPayStatus(20L);
                    detail.setCreateTime(new Date());
                    // 会进行原账单同步
                    remoteOrderService.insertPayStudentFeePaymentDetailVos(detail);
                }
                // 同步后开始支付
                // 拼装参数，进行支付内容发起
                // 使用 merchantPkId 分组并计算 totalAmount 总和，同时查询商户信息
                Map<Long, BigDecimal> merchantTotalMap = new HashMap<>();
                Map<Long, MerMerchantVos> merchantInfoMap = new HashMap<>();
                for (PayStudentFeePaymentDetailVos detail : details) {
                    Long merchantPkId = detail.getMerchantPkId();
                    BigDecimal totalAmount = detail.getTotalAmount();
                    // 累计计算相同商户的总额
                    merchantTotalMap.merge(merchantPkId, totalAmount, BigDecimal::add);
                    // 获取商户信息（仅获取一次）
                    if (!merchantInfoMap.containsKey(merchantPkId)) {
                        R<MerMerchantVos> merchantInfoR = remoteUserService.queryMerchantById(merchantPkId);
                        if (merchantInfoR.getData() != null) {
                            merchantInfoMap.put(merchantPkId, merchantInfoR.getData());
                        }
                    }
                }
                // 构建分账结果列表
                List<LeShuaShare> leShuaShareList = new ArrayList<>();
                BigDecimal totalMoney = details.stream()
                        .map(PayStudentFeePaymentDetailVos::getTotalAmount)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                for (Map.Entry<Long, BigDecimal> entry : merchantTotalMap.entrySet()) {
                    Long merchantPkId = entry.getKey();
                    BigDecimal shareMoney = entry.getValue();
                    // 获取商户信息
                    MerMerchantVos merchantInfo = merchantInfoMap.get(merchantPkId);
                    if (merchantInfo != null) {
                        LeShuaShare leShuaShare = new LeShuaShare();
                        leShuaShare.setMerchantId(123456L);
                        leShuaShare.setShareMerchantId(merchantPkId);
                        leShuaShare.setOrderId(orderNo);
                        leShuaShare.setTotalMoney(totalMoney);
                        leShuaShare.setMoney(shareMoney);
                        leShuaShare.setHighSchoolOrderId(generatePayNo);
                        leShuaShare.setStatus("0");
                        leShuaShare.setMerchantChannelCode("学校code");
                        leShuaShare.setShareChannelCode(merchantInfo.getMerchantCode());
                        leShuaShare.setMerchantName("学校名称");
                        leShuaShare.setShareName(merchantInfo.getMerchantName());
                        leShuaShareList.add(leShuaShare);
                    }
                }
                LeShuaShareVo leShuaShareVo = new LeShuaShareVo();
                leShuaShareVo.setShareMerchantList(leShuaShareList);
                // 发送给乐刷分账处，进行支付并进行分账
                R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId(payStudentFeePaymentVos.getStudentId(),payStudentFeePaymentVos.getFeeYearId());
                remoteUserService.insertStudentPayVos(listR.getData());



                return AjaxResult.success("抵扣金额成功！支付成功！");
            } catch (Exception e) {
                log.info("支付失败，请重新支付：{}", e.getMessage());
                return AjaxResult.error("支付失败，请重新支付");
            }
        }
    }



    //此接口用于支付成功的回调内容
    @PostMapping("/payResult")
    @Transactional
    public AjaxResult pay2(String payNumber){
        //TODO回调进行数据处理，修改状态
        log.info("支付成功回调内容：{}",payNumber);
        //修改订单状态   10待支付,20支付中,30支付成功,40支付失败,50已退款',
        Map<String, Object> map = remoteOrderService.updateAllPayStudentFeePayment(payNumber, 10L);
        R<List<StudentPayVos>> listR = remoteOrderService.selectStudentFeeByStudentId((Long) map.get("studentId"), (Long) map.get("feeYearId"));
        List<StudentPayVos> data = listR.getData();
        for (StudentPayVos studentPayVos : data){
            /** 支付状态0未支付1已支付2支付失败 */
            studentPayVos.setPayStatus(0L);
        }
        remoteUserService.updateStudentPayVos(listR.getData());
        return AjaxResult.success("完成");
    }





}
